﻿using System.Collections.Generic;
using System.Linq;
using HHPS.CreditEducation.DataProvider;
using HHPS.CreditEducation.Frameworks.Commons;
using HHPS.CreditEducation.Frameworks.Constants;

namespace HHPS.CreditEducation.Business
{
    public partial class Business
    {
        #region -- Get Course --

        /// <summary>
        /// This function shows list of courses.
        /// </summary>
        /// <returns></returns>
        public List<Course> GetListCourse()
        {
            return DataContex != null ? DataContex.Courses.ToList() : null;
        }

        #endregion

        #region Common

        private static bool CourseCommonValidator(Course course, out string message)
        {
            if (string.IsNullOrWhiteSpace(course.Name))
            {
                message = string.Format(ConstantMessages.RequireFieldIsBlank, "tên Kỳ");
                return false;
            }

            if (course.Name.Length >= 4)
            {
                message = string.Format(ConstantMessages.FieldDataOverMaxLength, "tên Kỳ", 4);
                return false;
            }
            message = string.Empty;
            return true;
        }

        #endregion

        #region -- Add Course --

        /// <summary>
        /// This function check validate of add a new facutly function
        /// </summary>
        /// <param name="course"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool AddNewCourseValidator(Course course, out string message)
        {
            if (!CourseCommonValidator(course, out message)) return false;

            if (DataContex.Courses.Any(c => c.Name.ToLower() == course.Name.ToLower()))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, course.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function add a new facutly into list.
        /// </summary>
        public void AddNewCourse(Course course)
        {
            DataContex.Courses.AddObject(course);
            DataContex.SaveChanges();

            //Add capacity
            var name = course.Name;
            course = DataContex.Courses.Single(c => c.Name == name);
            foreach (var major in DataContex.Courses)
            {
                DataContex.Capacities.AddObject(new Capacity { IdMajor = major.Id, IdCourse = course.Id, MaxCredit = 28, MinCredit = 15});
            }
            DataContex.SaveChanges();
        }

        #endregion

        #region -- Edit Course --

        /// <summary>
        /// This function check validate of edit a facutly function
        /// </summary>
        /// <param name="course"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool EditCourseValidator(Course course, out string message)
        {
            var id = course.Id;
            if (!DataContex.Courses.Any(c => c.Id == id))
            {
                message = ConstantMessages.CanNotIdentifyItem;
                return false;
            }

            if (!CourseCommonValidator(course, out message)) return false;

            if (DataContex.Courses.Any(c => c.Name.ToLower() == course.Name.ToLower() && c.Id != id))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, course.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function edits a facutly
        /// </summary>
        /// <param name="course"></param>
        public bool EditCourse(Course course)
        {
            var id = course.Id;
            var updateCourse = DataContex.Courses.SingleOrDefault(c => c.Id == id);

            if (updateCourse == null)
                return false;

            updateCourse.Name = course.Name;
            DataContex.SaveChanges();
            return true;
        }

        #endregion

        #region --Delete Course--

        /// <summary>
        /// This fuction checks validate of delete a major fuction
        /// </summary>
        /// <param name="courses"></param>
        /// <param name="message"></param>
        /// <returns></returns>       
        public bool DeleteCoursesValidator(IEnumerable<Course> courses, out string message)
        {
            const string intialize = "Ky: ";
            var itemsCannotIdentify = (from course in courses let id = course.Id where !DataContex.Courses.Any(c => c.Id == id) select course).Aggregate(intialize, (current, course) => current + (course.Name + ", "));

            if (itemsCannotIdentify != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsCanNotIdentify, itemsCannotIdentify.TrimEnd(','));
                return false;
            }

            message = string.Empty;
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="courses"></param>
        public void DeleteCourses(List<Course> courses)
        {
            for (var i = courses.Count - 1; i >= 0; i--)
            {
                var id = courses[i].Id;
                var deleteCourse = DataContex.Courses.Single(c => c.Id == id);

                //Delete capacity
                var capacities = DataContex.Capacities.Where(c => c.IdCourse == id).ToList();
                for (var j = capacities.Count - 1; j >= 0; j--)
                {
                    var capId = capacities[j].Id;
                    var deleteCapacity = DataContex.Capacities.Single(c => c.Id == capId);
                    DataContex.Capacities.DeleteObject(deleteCapacity);
                }

                DataContex.Courses.DeleteObject(deleteCourse);
            }
            DataContex.SaveChanges();
        }

        #endregion
    }
}